<?php

namespace app\admin\controller;

use app\admin\model\SystemAdmin;
use app\admin\model\SystemQuick;
use app\admin\model\InsurancePolicy;
use app\admin\model\InsuranceReport;
use app\common\controller\AdminController;
use app\Request;
use Exception;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Db;

class Index extends AdminController
{

    /**
     * 后台主页
     * @param Request $request
     * @return string
     */
    public function index(Request $request): string
    {
        return $this->fetch('', ['admin' => $request->adminUserInfo,]);
    }

    /**
     * 后台欢迎页
     * @return string
     * @throws Exception
     */
    public function welcome(): string
    {
        $tpVersion    = \think\facade\App::version();
        $mysqlVersion = Db::query("select version() as version")[0]['version'] ?? '未知';
        $phpVersion   = phpversion();
        $versions     = compact('tpVersion', 'mysqlVersion', 'phpVersion');
        $quick_list   = SystemQuick::field('id,title,icon,href')
            ->where(['status' => 1])->order('sort', 'desc')->limit(50)->select()->toArray();
        $quicks       = array_chunk($quick_list, 8);

        $today_total = InsurancePolicy::where('status', 1)->whereTime('create_at', 'today')->count()?:0;
        $month_total = InsurancePolicy::where('status', 1)->whereTime('create_at', 'month')->count()?:0;
        $year_total = InsurancePolicy::where('status', 1)->whereTime('create_at', 'year')->count()?:0;
        $this->assign([
            'today_total' => $today_total,
            'month_total' => $month_total,
            'year_total' => $year_total,
        ]);

        $month_billpay_total = InsurancePolicy::where('status', 1)->where('is_billpay', 1)->whereTime('create_at', 'month')->count()?:0;
        $month_billpay_no_total = InsurancePolicy::where('status', 1)->where('is_billpay',0)->whereTime('create_at', 'month')->count()?:0;

        $month_billpay_money_total = 0;
        $month_billpay_no_money_total = 0;
        $mbm_ids = InsurancePolicy::where('status', 1)->where('is_billpay', 1)->whereTime('create_at', 'month')->column('id');
        if (!empty($mbm_ids)) {
            $res0 = InsuranceReport::whereIn('policy_id', $mbm_ids)->field([
                'SUM(scharge_sy) AS ssy', 
                'SUM(scharge_jq) AS sjq',
                'SUM(scharge_jc) AS sjc',
            ])->find();
            $res1 = InsuranceReport::whereIn('policy_id', $mbm_ids)->field([
                'SUM(amount_sy) AS asy', 
                'SUM(amount_jq) AS ajq',
                'SUM(amount_jc) AS ajc',
            ])->find();
            $month_billpay_money_total = ($res0['ssy'] ?? 0) + ($res0['sjq'] ?? 0) + ($res0['sjc'] ?? 0);
            $month_billpay_no_money_total = ($res1['asy'] ?? 0) + ($res1['ajq'] ?? 0) + ($res1['ajc'] ?? 0) - $month_billpay_money_total;
        }
        $this->assign([
            'month_billpay_total' => $month_billpay_total,
            'month_billpay_no_total' => $month_billpay_no_total,
            'month_billpay_money_total' => $month_billpay_money_total,
            'month_billpay_no_money_total' => $month_billpay_no_money_total,
        ]);
        // 代理人统计
        // 每月每日统计 出单数 
        $agents = InsurancePolicy::group('agent')->field('agent')->select()->toArray() ?? [];
        $daysInMonth = cal_days_in_month(CAL_GREGORIAN, date('m'), date('Y'));
        $allDays = [];
        $allDays_tmp = [];
        for ($i = 1; $i <= $daysInMonth; $i++) {
            $allDays_tmp[] = sprintf('%04d-%02d-%02d', date('Y'), date('m'), $i);
            $allDays[] = [
                'day' => sprintf('%04d-%02d-%02d', date('Y'), date('m'), $i), // 替换为当前年份月份
                'time' => strtotime(sprintf('%04d-%02d-%02d', date('Y'), date('m'), $i)),
            ];
        }
        $months = [];
        $months_tmp = [];
        for ($i = 1; $i <= 12; $i++) {
            $months_tmp[] = sprintf('%04d-%02d', date('Y'), $i);
            $daysInMonth = cal_days_in_month(CAL_GREGORIAN, $i, date('Y'));
            $months[] = [
                'month' => sprintf('%04d-%02d', date('Y'), $i),
                'start_time' => strtotime(sprintf('%04d-%02d-01', date('Y'), $i)),
                'end_time' => strtotime(sprintf('%04d-%02d-%d 23:59:59', date('Y'), $i, $daysInMonth)),
            ];
        }
        $d_data = $agents;
        $m_data = $agents;
        $agents_tmp = $agents;
        foreach ($d_data as $k => $v) {
            $day_data = [];
            foreach ($allDays as $day) {
                // $agents[$k]['days'][$day['day']] = InsurancePolicy::where('agent', $v['agent'])->where('create_at', $day['time'])->count() ?? 0;
                $day_data[] = InsurancePolicy::where('agent', $v['agent'])->where('create_at', $day['time'])->count() ?? 0;
            }
            $d_data[$k]['data'] = $day_data;
            $d_data[$k]['type'] = 'line';
            $d_data[$k]['stack'] = '总量';
            $d_data[$k]['name'] = $v['agent'];
        }
        foreach ($m_data as $k => $v) {
            $month_data = [];
            foreach ($months as $month) {
                // $agents[$k]['months'][$month['month']] = InsurancePolicy::where('agent', $v['agent'])->whereBetweenTime('create_at', $month['start_time'], $month['end_time'])->count() ?? 0;
                $month_data[] = InsurancePolicy::where('agent', $v['agent'])->whereBetweenTime('create_at', $month['start_time'], $month['end_time'])->count() ?? 0;
            }
            $m_data[$k]['data'] = $month_data;
            $m_data[$k]['type'] = 'line';
            $m_data[$k]['stack'] = '总量';
            $m_data[$k]['name'] = $v['agent'];

        }
        foreach ($agents_tmp as $k => $v) {
            $agents_tmp[$k] = $v['agent'];
        }
        // echo '<pre>';
        // var_dump($months);
        // var_dump($agents);
        // 每年每月统计 出单数 
        $this->assign([
            'agents' => $agents_tmp,
            'months' => $months_tmp,
            'allDays' => $allDays_tmp,
            'd_data' => $d_data,
            'm_data' => $m_data,
        ]);
        $this->assign(compact('quicks', 'versions'));
        return $this->fetch();
    }

    /**
     * 修改管理员信息
     * @param Request $request
     * @return string
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function editAdmin(Request $request): string
    {
        $id  = $this->adminUid;
        $row = (new SystemAdmin())
            ->withoutField('password')
            ->find($id);
        empty($row) && $this->error('用户信息不存在');
        if ($request->isPost()) {
            $post = $request->post();
            $this->isDemo && $this->error('演示环境下不允许修改');
            $rule = [];
            $this->validate($post, $rule);
            try {
                $login_type = $post['login_type'] ?? 1;
                if ($login_type == 2) {
                    $ga_secret = (new SystemAdmin())->where('id', $id)->value('ga_secret');
                    if (empty($ga_secret)) $this->error('请先绑定谷歌验证器');
                }
                $save = $row->allowField(['head_img', 'phone', 'remark', 'update_time', 'login_type'])->save($post);
            }catch (\PDOException $e) {
                $this->error('保存失败');
            }
            $save ? $this->success('保存成功') : $this->error('保存失败');
        }
        $this->assign('row', $row);
        $notes = (new SystemAdmin())->notes;
        $this->assign('notes', $notes);
        return $this->fetch();
    }

    /**
     * 修改密码
     * @param Request $request
     * @return string
     */
    public function editPassword(Request $request): string
    {
        $id  = $this->adminUid;
        $row = (new SystemAdmin())
            ->withoutField('password')
            ->find($id);
        if (!$row) {
            $this->error('用户信息不存在');
        }
        if ($request->isPost()) {
            $post = $request->post();
            $this->isDemo && $this->error('演示环境下不允许修改');
            $rule = [
                'password|登录密码'       => 'require',
                'password_again|确认密码' => 'require',
            ];
            $this->validate($post, $rule);
            if ($post['password'] != $post['password_again']) {
                $this->error('两次密码输入不一致');
            }

            try {
                $save = $row->save([
                    'password' => password_hash($post['password'], PASSWORD_DEFAULT),
                ]);
            }catch (Exception $e) {
                $this->error('保存失败');
            }
            if ($save) {
                $this->success('保存成功');
            }else {
                $this->error('保存失败');
            }
        }
        $this->assign('row', $row);
        return $this->fetch();
    }

    /**
     * 设置谷歌验证码
     * @param Request $request
     * @return string
     * @throws Exception
     */
    public function set2fa(Request $request): string
    {
        $id  = $this->adminUid;
        $row = (new SystemAdmin())->withoutField('password')->find($id);
        if (!$row) $this->error('用户信息不存在');
        // You can see: https://gitee.com/wolf-code/authenticator
        $ga = new \Wolfcode\Authenticator\google\PHPGangstaGoogleAuthenticator();
        if (!$request->isAjax()) {
            $old_secret = $row->ga_secret;
            $secret     = $ga->createSecret(32);
            $ga_title   = $this->isDemo ? 'EasyAdmin8演示环境' : '可自定义修改显示标题';
            $dataUri    = $ga->getQRCode($ga_title, $secret);
            $this->assign(compact('row', 'dataUri', 'old_secret', 'secret'));
            return $this->fetch();
        }
        $this->isDemo && $this->error('演示环境下不允许修改');
        $post      = $request->post();
        $ga_secret = $post['ga_secret'] ?? '';
        $ga_code   = $post['ga_code'] ?? '';
        if (empty($ga_code)) $this->error('请输入验证码');
        if (!$ga->verifyCode($ga_secret, $ga_code)) $this->error('验证码错误');
        $row->ga_secret  = $ga_secret;
        $row->login_type = 2;
        $row->save();
        $this->success('操作成功');
    }

}
